package com.frame.auth.mvc.web;

import com.frame.common.tools.result.ServiceResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;

/**
 * @auther zhangwj
 * @date 2021/3/19 上午10:47
 */
@RestController
@RequestMapping(value = "access")
@PropertySource(value = "classpath:config.properties")
public class AccessController {

    @Value(value = "${cloud.auth.server.path}")
    private String serverUrl;

    private final static String GET_TOKEN_URL = "/oauth/token";

    private final static String GET_AUTH_URL = "/oauth/authorize";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping(value = "getCode")
    public ModelAndView getCode(@RequestParam(value = "appKey", required = false) String appKey,
                                @RequestParam(value = "scope", required = false) String scope) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("client_id", appKey);
        modelAndView.addObject("response_type", "code");
        modelAndView.addObject("scope", scope);
        modelAndView.addObject("grant_type", "authorization_code");
        modelAndView.setViewName("redirect:" + serverUrl + GET_AUTH_URL);
        return modelAndView;
    }

    @PostMapping(value = "getTokenByCode")
    public Object getTokenByCode(@RequestParam(value = "appKey", required = false) String appKey,
                                 @RequestParam(value = "appSecret", required = false) String appSecret,
                                 @RequestParam(value = "code", required = false) String code) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpMethod method = HttpMethod.POST;
        // 以表单的方式提交
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("client_id", appKey);
        params.add("client_secret", appSecret);
        params.add("response_type", "token");
        params.add("code", code);
        params.add("grant_type", "authorization_code");
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        return restTemplate.exchange(serverUrl + GET_TOKEN_URL, method, requestEntity, ServiceResult.class).getBody();
    }

    @GetMapping(value = "getTokenByImplicit")
    public ModelAndView getTokenByImplicit(@RequestParam(value = "appKey", required = false) String appKey,
                                           @RequestParam(value = "appSecret", required = false) String appSecret,
                                           @RequestParam(value = "scope", required = false) String scope) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("client_id", appKey);
        modelAndView.addObject("client_secret", appSecret);
        modelAndView.addObject("scope", scope);
        modelAndView.addObject("response_type", "token");
        modelAndView.addObject("grant_type", "implicit");
        modelAndView.setViewName("redirect:" + serverUrl + GET_AUTH_URL);
        return modelAndView;
    }

    @PostMapping(value = "getTokenByPassword")
    public Object getTokenByPassword(@RequestParam(value = "appKey", required = false) String appKey,
                                     @RequestParam(value = "appSecret", required = false) String appSecret,
                                     @RequestParam(value = "userName", required = false) String userName,
                                     @RequestParam(value = "password", required = false) String password,
                                     @RequestParam(value = "scope", required = false) String scope) {
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = HttpMethod.POST;
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("client_id", appKey);
        params.add("client_secret", appSecret);
        params.add("password", password);
        params.add("username", userName);
        params.add("scope", scope);
        params.add("grant_type", "password");
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        return restTemplate.exchange(serverUrl + GET_TOKEN_URL, method, requestEntity, ServiceResult.class).getBody();
    }

    @PostMapping(value = "getTokenByClient")
    public Object getTokenByClient(@RequestParam(value = "appKey", required = false) String appKey,
                                   @RequestParam(value = "appSecret", required = false) String appSecret,
                                   @RequestParam(value = "scope", required = false) String scope) {
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = HttpMethod.POST;
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("client_id", appKey);
        params.add("scope", scope);
        params.add("client_secret", appSecret);
        params.add("grant_type", "client_credentials");
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        return restTemplate.exchange(serverUrl + GET_TOKEN_URL, method, requestEntity, ServiceResult.class).getBody();
    }

    @PostMapping(value = "getRefreshToken")
    public Object getRefreshToken(@RequestParam(value = "refreshToken", required = false) String refreshToken) {
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = HttpMethod.POST;
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("refresh_token", refreshToken);
        params.add("grant_type", "refresh_token");
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        return restTemplate.exchange(serverUrl + GET_TOKEN_URL, method, requestEntity, ServiceResult.class).getBody();
    }
}
